package org.liukai.tutorial.service;

import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.liukai.tutorial.domain.Authority;
import org.liukai.tutorial.domain.Role;
import org.liukai.tutorial.domain.User;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Sets;

@Transactional(readOnly = true)
public class UserDetailsServiceImpl implements UserDetailsService {

	protected static Logger logger = Logger.getLogger("service");

	@Resource(name = "accountService")
	private IAccountService service;

	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {

		User user = service.getUserInfo(username);

		if (user == null) {
			throw new UsernameNotFoundException("用户{ " + username + " }不存在!");
		}

		Set<GrantedAuthority> grantedAuths = obtainGrantedAuthorities(user);

		// -- mini-web示例中无以下属性, 暂时全部设为true. --//
		boolean enabled = true;
		boolean accountNonExpired = true;
		boolean credentialsNonExpired = true;
		boolean accountNonLocked = true;

		UserDetails userdetails = new org.springframework.security.core.userdetails.User(
				user.getLoginName(), user.getPassword(), enabled,
				accountNonExpired, credentialsNonExpired, accountNonLocked,
				grantedAuths);

		return userdetails;
	}

	/**
	 * 获得当前User的权限('ROLE_' 开头的)
	 */
	private Set<GrantedAuthority> obtainGrantedAuthorities(User user) {

		Set<GrantedAuthority> authSet = Sets.newHashSet();

		for (Role role : user.getRoleList()) {
			for (Authority authority : role.getAuthorityList()) {
				authSet.add(new GrantedAuthorityImpl(authority
						.getPrefixedName()));
			}
		}

		return authSet;

	}

}
